home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / WORN.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  5KB  |  174 lines

  1. /*    SCCS Id: @(#)worn.c    3.0    89/11/15
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. static const char crispy[] = "The flames of hell burn you to a crisp.";
  8. static void FDECL(set_armor_intrinsic, (struct obj *,BOOLEAN_P));
  9.  
  10. const struct worn {
  11.     long w_mask;
  12.     struct obj **w_obj;
  13. } worn[] = {
  14.     { W_ARM, &uarm },
  15.     { W_ARMC, &uarmc },
  16.     { W_ARMH, &uarmh },
  17.     { W_ARMS, &uarms },
  18.     { W_ARMG, &uarmg },
  19.     { W_ARMF, &uarmf },
  20. #ifdef SHIRT
  21.     { W_ARMU, &uarmu },
  22. #endif
  23.     { W_RINGL, &uleft },
  24.     { W_RINGR, &uright },
  25.     { W_WEP, &uwep },
  26.     { W_AMUL, &uamul },
  27.     { W_TOOL, &ublindf },
  28.     { W_BALL, &uball },
  29.     { W_CHAIN, &uchain },
  30.     { 0, 0 }
  31. };
  32.  
  33. void
  34. setworn(obj, mask)
  35. register struct obj *obj;
  36. long mask;
  37. {
  38.     register const struct worn *wp;
  39.     register struct obj *oobj = 0;
  40.  
  41.     for(wp = worn; wp->w_mask; wp++) if(wp->w_mask & mask) {
  42.         oobj = *(wp->w_obj);
  43.         if(oobj && !(oobj->owornmask & wp->w_mask))
  44.             impossible("Setworn: mask = %ld.", wp->w_mask);
  45.         if(oobj) {
  46.             oobj->owornmask &= ~wp->w_mask;
  47.             /* leave as "x = x <op> y", here and below, for broken
  48.              * compilers */
  49.             u.uprops[objects[oobj->otyp].oc_oprop].p_flgs = 
  50.                 u.uprops[objects[oobj->otyp].oc_oprop].p_flgs & 
  51.                 ~wp->w_mask;
  52.             set_armor_intrinsic(oobj, 0);
  53.         }
  54.         *(wp->w_obj) = obj;
  55.         if(obj) {
  56.             obj->owornmask |= wp->w_mask;
  57.         /* prevent getting intrinsics from wielding potions, etc... */
  58.         /* wp_mask should be same as mask at this point */
  59.             if(obj->olet == WEAPON_SYM || mask != W_WEP) {
  60.             u.uprops[objects[obj->otyp].oc_oprop].p_flgs = 
  61.                 u.uprops[objects[obj->otyp].oc_oprop].p_flgs | 
  62.                 wp->w_mask;
  63.             set_armor_intrinsic(obj, 1);
  64.             }
  65.         }
  66.     }
  67.     /* A kludge to solve the problem of someone gaining fire resistance
  68.      * only from an item, then entering Hell and removing/unwielding it.
  69.      * Checking this every time setworn gets called is a bit of an
  70.      * overkill. --KAA
  71.      */
  72.     if (Inhell && !Fire_resistance) {
  73.         pline(crispy);
  74.         killer_format = NO_KILLER_PREFIX;
  75.         killer = self_pronoun("lost %s fire protection in hell","his");
  76.         done(BURNING);
  77.         /* If we're here they survived with life saving, so put the
  78.          * weapon they just unwielded back in their hands...
  79.          */
  80.         if (!oobj || (oobj->otyp != DRAGON_SCALE_MAIL
  81.                 && oobj->otyp != RIN_FIRE_RESISTANCE
  82. #ifdef NAMED_ITEMS
  83.                 && !defends(AD_FIRE, oobj)
  84. #endif
  85.                 && oobj->corpsenm != PM_RED_DRAGON))
  86.             impossible("lost FR from a non-FR item?");
  87.         setworn(oobj, mask);
  88.     }
  89. }
  90.  
  91. /* called e.g. when obj is destroyed */
  92. void
  93. setnotworn(obj)
  94. register struct obj *obj;
  95. {
  96.     register const struct worn *wp;
  97.  
  98.     if (!obj) return;
  99.     for(wp = worn; wp->w_mask; wp++)
  100.         if(obj == *(wp->w_obj)) {
  101.             *(wp->w_obj) = 0;
  102.             u.uprops[objects[obj->otyp].oc_oprop].p_flgs = 
  103.                 u.uprops[objects[obj->otyp].oc_oprop].p_flgs & 
  104.                     ~wp->w_mask;
  105.             obj->owornmask &= ~wp->w_mask;
  106.             set_armor_intrinsic(obj, 0);
  107.         }
  108.     /* See comments above in setworn().  The major difference is the
  109.      * need to check AMULET_SYM so if someone goes to Hell without
  110.      * being fire resistant, then dies, when their amulet saves them
  111.      * and disintegrates this code will not be triggered. --KAA
  112.      */
  113.     if (Inhell && !Fire_resistance && obj->olet != AMULET_SYM) {
  114.         pline(crispy);
  115.         killer_format = NO_KILLER_PREFIX;
  116.         killer = self_pronoun("lost %s fire protection in hell","his");
  117.         done(BURNING);
  118.         /* Survived with lifesaving, etc...; there's no general way
  119.          * to undo the setnotworn()--we can't re-wear/wield the
  120.          * item since it might have been stolen, disintegrated, etc....
  121.          */
  122. #if defined(WIZARD) || defined(EXPLORE_MODE)
  123.         while(1) {
  124.             /* keep doing it until they finally decide they really
  125.              * _do_ want to die, since we can't possibly continue
  126.              * the game from this point...
  127.              */
  128. #endif
  129.             You("are still burning and die again...");
  130.             done(BURNING);
  131. #if defined(WIZARD) || defined(EXPLORE_MODE)
  132.         }
  133. #endif
  134.     }
  135. }
  136.  
  137. static void
  138. set_armor_intrinsic(obj,on)
  139. register struct obj *obj;
  140. boolean on;
  141. {
  142.     long *mask;
  143.  
  144.     if (obj->otyp != DRAGON_SCALE_MAIL) return;
  145.     switch(obj->corpsenm) {
  146.         case PM_GRAY_DRAGON:
  147.             mask = &Antimagic;
  148.             break;
  149.         case PM_RED_DRAGON:
  150.             mask = &HFire_resistance;
  151.             break;
  152.         case PM_WHITE_DRAGON:
  153.             mask = &HCold_resistance;
  154.             break;
  155.         case PM_BLUE_DRAGON:
  156.             mask = &HShock_resistance;
  157.             break;
  158.         case PM_GREEN_DRAGON:
  159.             mask = &HPoison_resistance;
  160.             break;
  161.         case PM_ORANGE_DRAGON:
  162.             mask = &HSleep_resistance;
  163.             break;
  164.         case PM_BLACK_DRAGON:
  165.             mask = &HDisint_resistance;
  166.             break;
  167.         case PM_YELLOW_DRAGON:
  168.         default:
  169.             return;
  170.     }
  171.     if (on) *mask |= WORN_ARMOR;
  172.     else *mask &= ~WORN_ARMOR;
  173. }
  174.